/**
 * index.js 主页
 * 
 * @author zhongweizhang@163.com
 * @description 无
 */
Ext
		.onReady(function() {

			var sample = {
				"jdbcUrl" : null,
				"map" : {
					"tables" : [ "", "", "", "", "", "", "" ],
					"schemas" : [ "", "", "", "", "", "", "" ],
					"scals" : [ 0, 0, 0, 0, 2, 0, 0 ],
					"columnPrecisions" : [ 0, 30, 0, 10, 10, 4, 2 ],
					"columnTypes" : [ 2, 12, 91, 2, 2, 2, 2 ],
					"columnTypeNames" : [ "NUMBER", "VARCHAR2", "DATE",
							"NUMBER", "NUMBER", "NUMBER", "NUMBER" ],
					"columnNames" : [ "SAMPLE_ID", "SAMPLE_NAME",
							"SAMPLE_DATE", "SAMPLE_LONG", "SAMPLE_DOUBLE",
							"SAMPLE_INT", "SAMPLE_BYTE" ],
					"columnClassNames" : [ "java.math.BigDecimal",
							"java.lang.String", "java.sql.Date",
							"java.math.BigDecimal", "java.math.BigDecimal",
							"java.math.BigDecimal", "java.math.BigDecimal" ]
				},
				"password" : null,
				"sql" : "select * from sample",
				"success" : true,
				"user" : null
			};
			// 转换字符串为首字母大写其它全部小写
			var pinStr = function(str) {
				if (Ext.isEmpty(str))
					return '';
				var begin = '';

				begin = str.substr(0, 1).toUpperCase();

				var others = '';
				if (str.length > 1)
					others = str.substr(1).toLowerCase();

				return begin + others;
			};

			// 转换首字母大写或小写
			var chUpLow = function(str, iflow) {
				if (Ext.isEmpty(str))
					return '';
				var begin = '';

				begin = str.substr(0, 1);

				if (iflow) {
					begin = begin.toLowerCase();
				} else {
					begin = begin.toUpperCase();
				}

				var others = '';
				if (str.length > 1)
					others = str.substr(1);

				return begin + others;

			};

			// 根据数据库字段类型生成类名
			var genClassName = function(typeName, scale, precious) {
				if (typeName == 'VARCHAR2') {
					var rtn = propPn.source.VARCHAR2;
					return Ext.isEmpty(rtn) ? 'String' : rtn;
				} else if (typeName == 'DATE') {
					var rtn = propPn.source.DATE;
					return Ext.isEmpty(rtn) ? 'Date' : rtn;
				} else if (typeName == 'NUMBER') {
					if (scale > 0) {
						var rtn = propPn.source.NUMBERNN;
						return Ext.isEmpty(rtn) ? 'double' : rtn;
					} else if (precious > 9) {
						var rtn = propPn.source.NUMBERGT9;
						return Ext.isEmpty(rtn) ? 'long' : rtn;
					} else if (precious > 4) {
						var rtn = propPn.source.NUMBERGT4;
						return Ext.isEmpty(rtn) ? 'int' : rtn;
					} else if (precious > 2) {
						var rtn = propPn.source.NUMBERGT2;
						return Ext.isEmpty(rtn) ? 'short' : rtn;
					} else if (precious == 2) {
						var rtn = propPn.source.NUMBER2;
						return Ext.isEmpty(rtn) ? 'Byte' : rtn;
					} else if (precious == 1) {
						var rtn = propPn.source.NUMBER1;
						return Ext.isEmpty(rtn) ? 'boolean' : rtn;
					} else {
						return 'BigDecimal';
					}

				}
				// 待添加非常用类型
				else {
					return 'UNKNOWN';
				}

			};

			// 转换数据库字段名称为Java名称
			var comboStr = function(str) {

				if (Ext.isEmpty(str))
					return '';
				var rtn = '';

				// 使用自定义的分隔符进行分隔 ， 默认数据库中字段名是以'-' 分隔的
				var separator = classPn.source.DataFieldSeparater;
				separator = Ext.isEmpty(separator) ? '_' : separator;
				var arr = str.split(separator);

				var len = arr.length;
				if (len > 0)
					rtn += arr[0].toLowerCase();
				if (len > 1)
					for ( var i = 1; i < len; i++) {
						rtn += pinStr(arr[i]);
					}

				return rtn;

			};

			var genPojo = function(metaData) {
				if (Ext.isEmpty(metaData))
					return;
				// 组合POJO类
				var pcn = classPn.source.pojoClassName;

				// 如果没设置自定义名字，命名PojoClass 后台取不到名字:)
				pcn = Ext.isEmpty(pcn) || pcn == 'default' ? 'PojoClass' : pcn;

				var pojo = 'public class ' + pcn + '{\n';
				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {
					var member = 'private ';

					// 组合类名
					member += genClassName(metaData.columnTypeNames[i],
							metaData.scals[i], metaData.columnPrecisions[i]);

					member += ' ' + comboStr(metaData.columnNames[i]) + '; \n';
					str.push(member);
				}

				pojo += str.join('');

				pojo += '\n}';

				pojoTx.setValue(pojo);
			};

			var genRowMapper = function(metaData) {
				if (Ext.isEmpty(metaData))
					return;
				// 组合POJO类
				var pcn = classPn.source.pojoClassName;

				// 如果没设置自定义名字，命名PojoClass 后台取不到名字:)
				pcn = Ext.isEmpty(pcn) || pcn == 'default' ? 'PojoClass' : pcn;
				// 小写，做为返回变量名
				var pcl = chUpLow(pcn, true);
				// 防止小写做为类名时类名与变量名冲突
				pcl = pcl == pcn ? pcl + '1' : pcl;

				var rmn = classPn.source.rowMapperName;
				rmn = Ext.isEmpty(rmn) || rmn == 'default' ? 'PojoRowMapper'
						: rmn;

				var pojo = 'public class ' + rmn;
				pojo += " implements RowMapper<" + pcn + ">";
				pojo += " {\n @Override \n";
				pojo += "public   " + pcn;
				pojo += " mapRow(ResultSet rs, int paramInt) throws SQLException { \n";
				pojo += pcn + " " + pcl + " = new ";
				pojo += pcn + "();\n try { \n";
				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {

					var fieldName = comboStr(metaData.columnNames[i]);
					var member = pcl + '.set';
					member += chUpLow(fieldName);
					member += '(rs.get';

					// member += chUpLow(fieldName);
					member += chUpLow(genClassName(metaData.columnTypeNames[i],
							metaData.scals[i], metaData.columnPrecisions[i]));
					member += '("';

					member += metaData.columnNames[i];
					// 组合类名

					member += '")';
					member += ');\n';

					str.push(member);
				}

				pojo += str.join('');

				pojo += "return " + pcl + ";\n";
				pojo += "}catch (SQLException se) {\n" + "throw se;\n }\n}\n}";

				rmTx.setValue(pojo);
			};

			// Insert Dao生成
			var genInsert = function(metaData) {
				if (Ext.isEmpty(metaData))
					return;
				// 组合POJO类
				var pcn = classPn.source.pojoClassName;

				// 如果没设置自定义名字，命名PojoClass 后台取不到名字:)
				pcn = Ext.isEmpty(pcn) || pcn == 'default' ? 'PojoClass' : pcn;
				// 小写，做为返回变量名
				var pcl = chUpLow(pcn, true);
				// 防止小写做为类名时类名与变量名冲突
				pcl = pcl == pcn ? pcl + '1' : pcl;

				var rmn = classPn.source.rowMapperName;
				rmn = Ext.isEmpty(rmn) || rmn == 'default' ? 'PojoRowMapper'
						: rmn;

				var insMem = "public int insert" + pcn + "(" + pcn + " " + pcl
						+ "){\n";
				insMem += "SimpleJdbcInsert sji = new SimpleJdbcInsert(getDataSource());\n";
				insMem += "sji.withTableName(" + "\"*TABLENAME*\"" + ");\n";
				insMem += "Map<String, Object> map = new HashMap<String, Object>();\n";

				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {
					var fieldName = comboStr(metaData.columnNames[i]);
					var member = "";
					member += "map.put(\"" + metaData.columnNames[i] + "\"," + pcl + ".get";
					member += chUpLow(fieldName);
					member += "());\n";
					str.push(member);
				}

				insMem += str.join("");
				insMem += " \n return sji.execute(map);\n";
				insMem += "}";

				insertTx.setValue(insMem);
			};

			// Update Dao生成
			var genUpdate = function(metaData) {
				if (Ext.isEmpty(metaData))
					return;
				// 组合POJO类
				var pcn = classPn.source.pojoClassName;

				// 如果没设置自定义名字，命名PojoClass 后台取不到名字:)
				pcn = Ext.isEmpty(pcn) || pcn == 'default' ? 'PojoClass' : pcn;
				// 小写，做为返回变量名
				var pcl = chUpLow(pcn, true);
				// 防止小写做为类名时类名与变量名冲突
				pcl = pcl == pcn ? pcl + '1' : pcl;

				var rmn = classPn.source.rowMapperName;
				rmn = Ext.isEmpty(rmn) || rmn == 'default' ? 'PojoRowMapper'
						: rmn;

				var insMem = "public int update" + pcn + "(" + pcn + " " + pcl
						+ "){\n";

				insMem += "StringBuffer sb = new StringBuffer();\n";
				insMem += "sb.append(\"UPDATE *TABLENAME* \\n SET \\n\");\n";
				var upsql = [];

				for ( var i = 0; i < metaData.tables.length; i++) {
					var fieldName = metaData.columnNames[i];
					var mem = "";
					mem += "sb.append(\" " + fieldName + "=:" + fieldName
							+ " ,\\n\");\n";

					upsql.push(mem);
				}

				insMem += upsql.join("");

				insMem+="sb.append(\" WHERE " +metaData.columnNames[0] +"=:"+metaData.columnNames[0] +"\\n\");\n";
				insMem += "String sql = sb.toString();\n";

				insMem += "Map<String, Object> map = new HashMap<String, Object>();\n";

				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {
					var fieldName = comboStr(metaData.columnNames[i]);
					var member = "";
					member += "map.put(\"" + metaData.columnNames[i] + "\"," + pcl + ".get";
					member += chUpLow(fieldName);
					member += "());\n";
					str.push(member);
				}

				insMem += str.join("");
				insMem += " \n return super.update(sql, map);\n";
				insMem += "}";

				updateTx.setValue(insMem);
			};

			// store 生成
			var genStore = function(metaData) {
				var storestr = ' new Ext.data.Store({'
						+ 'proxy : new Ext.data.HttpProxy({      \n'
						+ '			url : \'添加URL\'      \n' + '			}),\n'
						+ 'reader : new Ext.data.JsonReader({    \n'
						+ '			root : \'添加ROOT\'\n' + '		}, [';
				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {

					var fieldName = comboStr(metaData.columnNames[i]);

					var member = '{';

					member += 'name:';
					member += '"' + fieldName + '"';

					if (metaData.columnTypeNames[i] == 'DATE') {
						member += ', type:';
						member += '"date"';
					} else if (metaData.columnTypeNames[i] == 'NUMBER'
							&& metaData.scals[i] == 0
							&& metaData.columnPrecisions[i] == 1) {
						member += ', type:';
						member += '"boolean"';
					}
					// TODO: 待添加 int float 等类型

					member += '}\n';

					str.push(member);
				}

				storestr += str.join(',');
				storestr += ']) \n });';

				storeTx.setValue(storestr);
			};

			// Field 生成
			var genField = function(metaData) {

				var fieldstr = '';
				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {

					var fieldName = comboStr(metaData.columnNames[i]);
					var member = '';
					if (metaData.columnTypeNames[i] == 'DATE') {
						member += "new Ext.form.DateField({name : '"
								+ fieldName + "',\n";
						member += "format : 'Y-m-d',\n";
						member += "	emptyText : '请输入" + fieldName + " ',\n";
						member += "fieldLabel : '" + fieldName + "'	})	\n";
					} else if (metaData.columnTypeNames[i] == 'NUMBER') {
						member += "new Ext.form.NumberField({name : '"
								+ fieldName + "',\n";
						member += "	emptyText : '请输入" + fieldName + " ',\n";
						member += "fieldLabel : '" + fieldName + "'	})	\n";
					} else {
						member += "new Ext.form.TextField({name : '"
								+ fieldName + "',\n";
						member += "	emptyText : '请输入" + fieldName + " ',\n";
						member += "fieldLabel : '" + fieldName + "'	})	\n";
					}

					// 未处理boolean 类型 和对 Number 细分

					str.push(member);

				}
				fieldstr += str.join(',');
				fieldTx.setValue(fieldstr);
			};

			// ColumnModel 生成
			var genColumn = function(metaData) {

				colstr = 'new Ext.grid.ColumnModel([\n';
				var str = [];

				for ( var i = 0; i < metaData.tables.length; i++) {
					var member = '';
					var fieldName = comboStr(metaData.columnNames[i]);

					member += "{ header:'" + fieldName + "',dataIndex:'"
							+ fieldName + "'";
					if (metaData.columnTypeNames[i] == 'DATE') {
						member += ",type:'date'";
					} else if (metaData.columnTypeNames[i] == 'NUMBER'
							&& metaData.scals[i] == 0
							&& metaData.columnPrecisions[i] == 1) {
						member += ",type:'boolean'";
					} else if (metaData.columnTypeNames[i] == 'NUMBER'
							&& metaData.scals[i] == 0) {
						member += ",type:'long'";
					} else if (metaData.columnTypeNames[i] == 'NUMBER'
							&& metaData.scals[i] !== 0) {
						member += ",type:'float'";
					} else {

					}

					member += "}\n";

					str.push(member);

				}

				colstr += str.join(',') + '\n]);';

				columnTx.setValue(colstr);

			};

			var processMetaData = function(response) {

				var obj = Ext.decode(response.responseText);

				var md = obj.map;

				// pojo类生成
				genPojo(md);

				// RowMapper类生成
				genRowMapper(md);

				// store 生成
				// genStore(md);

				// FormField
				// genField(md);

				// Column
				// genColumn(md);
				genInsert(md);
				genUpdate(md);

			};

			// 类文本请求方法
			var genClasses = function() {
				if (Ext.isEmpty(sqlTx.getValue()))
					return;
				var params = {
					sql : sqlTx.getValue()
				};
				Ext.apply(params, propPn.source);

				Ext.Ajax.request({
					url : './code/genjdbccode!genMetaData.action',
					params : params,
					success : processMetaData
				});

			};

			// 数据连接测试请求
			var testDataSource = function() {
				var myMask = new Ext.LoadMask(dsPn.getId(), {
					msg : "正在测试连接..."
				});
				myMask.show();
				Ext.Ajax.request({
					url : './code/genjdbccode!testDataSource.action',
					method : 'POST',
					params : dsPn.source,
					success : function(response) {
						var obj = Ext.decode(response.responseText);
						if (obj && obj.success) {
							Ext.MessageBox.alert('提示', '连接成功并保存');
						} else {
							Ext.MessageBox.alert('提示', '连接失败');
						}
					},
					callback : function(op, su, res) {
						myMask.hide();
						myMask.destroy();
					}
				});
			};

			// 以下为界面构造
			// banner
			var barpn = new Ext.Panel({
				region : 'north',
				height : 60,
				html : '<center><font size=7 >JDBC 代码辅助生成器</font></center>'
			});

			// 类属性
			var classPn = new Ext.grid.PropertyGrid({
				title : '生成类名称',
				// cm : colModel,
				// data : data,

				source : {
					pojoClassName : 'default',
					rowMapperName : 'default',
					DataFieldSeparater : '_'
				}
			});

			// 数据库面板
			var dsPn = new Ext.grid.PropertyGrid({
				title : '数据库属性',
				border : false,
				propertyNames : {
					jdbcUrl : '数据库地址',
					user : "数据库用户名",
					password : "数据库密码"
				},
				source : {
					jdbcUrl : "192.168.2.143:1521:sea",
					user : "sea",
					password : "sea"
				},
				buttonAlign : 'center',
				buttons : [ {
					text : '测试',
					handler : testDataSource
				} ]
			});

			// 属性对应面板
			var propPn = new Ext.grid.PropertyGrid({
				title : '数据类型对应',
				// cm : colModel,
				// data : data,

				source : {
					VARCHAR2 : 'String',
					DATE : 'Date',
					NUMBER : 'double',
					NUMBERNN : 'double',
					NUMBERGT9 : 'long',
					NUMBERGT4 : 'int',
					NUMBERGT2 : 'short',
					NUBMER2 : 'Byte',
					NUMBER1 : 'boolean'

				}
			});

			// 左侧面板
			var leftPn = new Ext.Panel({
				region : 'west',
				width : 300,
				title : '系统设置',
				layout : 'accordion',
				collapsible : true,
				items : [ classPn, dsPn, propPn ]
			});

			// SQL 输入框
			var sqlTx = new Ext.form.TextArea({
				name : 'sqlTx',
				border : false
			});

			// SQL 面板
			var sqlPanel = new Ext.form.FormPanel({
				region : 'north',
				// border : false,
				collapsible : true,
				title : 'SQL语句',
				height : 200,
				autoScroll : true,
				layout : 'fit',
				items : [ sqlTx ],
				buttonAlign : 'center',
				buttons : [ {
					text : '执行',
					handler : genClasses
				} ]
			});

			// POJO类的
			var pojoTx = new Ext.form.TextArea({
				name : 'pojoTx'
			});

			var pojoPn = new Ext.form.FormPanel({
				title : 'POJO类',
				layout : 'fit',
				autoScroll : true,
				items : [ pojoTx ]
			});

			// RowMapper
			var rmTx = new Ext.form.TextArea({
				name : 'rmTx'
			});

			var rmPn = new Ext.form.FormPanel({
				title : 'RowMapper类',
				layout : 'fit',
				autoScroll : true,
				items : [ rmTx ]
			});

			// Store
			var storeTx = new Ext.form.TextArea({
				name : 'storeTx'
			});

			var storePn = new Ext.form.FormPanel({
				title : 'STORE',
				layout : 'fit',
				autoScroll : true,
				items : [ storeTx ]
			});

			// Field
			var fieldTx = new Ext.form.TextArea({
				name : 'fieldTx'
			});

			var fieldPn = new Ext.form.FormPanel({
				title : 'FormField',
				layout : 'fit',
				autoScroll : true,
				items : [ fieldTx ]
			});

			// ColumnModel
			var columnTx = new Ext.form.TextArea({
				name : 'columnTx'
			});

			var columnPn = new Ext.form.FormPanel({
				title : 'ColumnModel',
				layout : 'fit',
				autoScroll : true,
				items : [ columnTx ]
			});

			var insertTx = new Ext.form.TextArea({
				name : 'insertTx'
			});

			var insertPn = new Ext.form.FormPanel({
				title : 'InsertPn',
				layout : 'fit',
				autoScroll : true,
				items : [ insertTx ]
			});

			// updatePn
			var updateTx = new Ext.form.TextArea({
				name : 'updateTx'
			});

			var updatePn = new Ext.form.FormPanel({
				title : 'updatePn',
				layout : 'fit',
				autoScroll : true,
				items : [ updateTx ]
			});

			// 工作窗口
			var outPn = new Ext.TabPanel({
				region : 'center',
				border : false,
				activeTab : 0,
				items : [ pojoPn, rmPn, insertPn, updatePn ]
			});

			var mainpn = new Ext.Panel({
				region : 'center',
				layout : 'border',
				border : false,
				items : [ sqlPanel, outPn ]
			});

			// 渲染主窗口
			var vp = new Ext.Viewport({
				layout : 'border',
				items : [ barpn, leftPn, mainpn ]
			});

		});